package com.sky.controller.mock;

import com.alibaba.fastjson.JSONObject;
import com.sky.exception.OrderBusinessException;
import com.sky.utils.HttpClientUtil;
import com.sky.utils.WeChatUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@RestController
@RequestMapping("/mock/wechat")
public class MockWechatController {

    /**
     * 预支付交易单号存储
     */
    private final Map<String, JSONObject> orderPrepayMap = new ConcurrentHashMap<>();

    @Autowired
    private WeChatUtil weChatUtil;

    /**
     * 模拟微信支付下单接口
     *
     * @param requestBody 请求参数
     * @return 预支付交易单号
     */
    @PostMapping("/pay/transactions/jsapi")
    @ApiOperation(value = "微信预支付下单接口")
    public JSONObject prepay(@RequestBody JSONObject requestBody) {
        log.info("模拟预支付下单请求 {}", requestBody);
        // 1. 生成预支付交易单号
        String prepayId = String.valueOf(System.currentTimeMillis());
        // 2. 保存预支付交易单号和请求参数
        orderPrepayMap.put(prepayId, requestBody);
        // 3. 返回预支付交易单号
        JSONObject resultObj = new JSONObject();
        resultObj.put("prepay_id", prepayId);
        return resultObj;
    }

    /**
     * 模拟微信支付接口
     *
     * @param requestBody 请求参数
     * @return 支付结果
     */
    @PostMapping("/pay/transactions/confirm")
    @ApiOperation(value = "微信支付接口")
    public JSONObject confirm(@RequestBody JSONObject requestBody) {
        log.info("模拟支付请求 {}", requestBody);
        // 1. 获取预支付交易单号
        String packageStr = requestBody.getString("package");
        if (packageStr == null || !packageStr.startsWith("prepay_id=")) {
            throw new OrderBusinessException("预支付交易单号不存在");
        }
        String prepayId = packageStr.substring(10);

        // 2. 获取订单数据
        JSONObject orderRequest = orderPrepayMap.get(prepayId);
        if (orderRequest == null) {
            throw new OrderBusinessException("预支付交易数据不存在");
        }
        String outTradeNo = orderRequest.getString("out_trade_no");

        // 3. 模拟支付成功
        String transactionId = String.valueOf(System.currentTimeMillis());
        orderPrepayMap.remove(prepayId);
        log.info("支付成功: prepayId={} transactionId={}", prepayId, transactionId);

        // 4. 回调接口
        String notifyUrl = orderRequest.getString("notify_url");
        if (StringUtils.isNotBlank(notifyUrl)) {
            notify(notifyUrl, outTradeNo, transactionId);
        } else {
            log.warn("支付回调地址不存在 prepayId={} transactionId={}", prepayId, transactionId);
        }

        // 5. 返回结果
        JSONObject resultObj = new JSONObject();
        resultObj.put("code", 1);
        resultObj.put("message", "SUCCESS");
        return resultObj;
    }

    /**
     * 模拟微信退款接口
     *
     * @param requestBody 请求参数
     * @return 退款结果
     */
    @PostMapping("/refund/domestic/refunds")
    @ApiOperation(value = "微信退款接口")
    public JSONObject refund(@RequestBody JSONObject requestBody) {
        log.info("模拟退款请求 {}", requestBody);
        // 1. 获取预支付交易单号
        String outTradeNo = requestBody.getString("out_trade_no");
        if (outTradeNo == null) {
            throw new OrderBusinessException("订单号不存在");
        }

        // 2. 模拟退款成功
        String transactionId = String.valueOf(System.currentTimeMillis());
        log.info("退款成功: outTradeNo={} transactionId={}", outTradeNo, transactionId);

        // 3. 回调接口
        String notifyUrl = requestBody.getString("notify_url");
        if (StringUtils.isNotBlank(notifyUrl)) {
            notify(notifyUrl, outTradeNo, transactionId);
        } else {
            log.warn("退款回调地址不存在 outTradeNo={} transactionId={}", outTradeNo, transactionId);
        }

        // 4. 返回结果
        JSONObject resultObj = new JSONObject();
        resultObj.put("code", 1);
        resultObj.put("message", "SUCCESS");
        return resultObj;
    }

    /**
     * 回调通知
     *
     * @param notifyUrl 回调地址
     * @param outTradeNo 交易单号
     * @param transactionId 支付交易事务
     */
    private void notify(String notifyUrl, String outTradeNo, String transactionId) {
        try {
            // 加密数据
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("out_trade_no", outTradeNo);
            paramMap.put("transaction_id", transactionId);
            String plainText = JSONObject.toJSONString(paramMap);
            String encryptText = weChatUtil.encryptData(plainText);

            // 发送请求
            String resp = HttpClientUtil.doPost4Json(notifyUrl, encryptText);
            log.info("回调接口响应, resp={}", resp);
            JSONObject respObj = JSONObject.parseObject(resp);
            if (respObj != null && "SUCCESS".equals(respObj.getString("code"))) {
                log.info("回调接口成功");
            } else {
                log.error("回调接口失败, resp={}", resp);
            }
        } catch (Exception e) {
            log.error("回调接口异常", e);
        }
    }

}
